package com.jellyfishumbrella.GL;

import java.util.ArrayList;
import java.util.TreeSet;

public class KeyframeQueue<E> extends TreeSet<E> {// PriorityQueue<E> {
	public enum END_BEHAVIOR {
		RESET,
		CONSTANT,
		LOOP
	};

	public Keyframe		currKey, nextKey, prevKey, here;
	public END_BEHAVIOR	endBehavior	= END_BEHAVIOR.LOOP;
	public long			duration	= 1;

	@SuppressWarnings("unchecked")
	public KeyframeQueue() {
		super();
		currKey = null;
		nextKey = null;
		prevKey = null;

		here = new Keyframe(0);

		add((E) here);
	}

	public boolean add(E o) {
		boolean r = super.add(o);

		if (r) {
			defineMainKeyframes(0);
		}

		return r;
	}

	@SuppressWarnings("unchecked")
	public void defineMainKeyframes(long worldTime) {
		long currTime = currTime(worldTime);
		if (currTime != 0) {
			currKey = new Keyframe(currTime);
			currKey = (Keyframe) lower((E) currKey);
		} else {
			currKey = (Keyframe) first();
		}
		if (currKey == null) {
			currKey = (Keyframe) first();
		}

		definePrevNextKeyframes();
		
	}

	@SuppressWarnings("unchecked")
	public void definePrevNextKeyframes() {
		try {
			prevKey = (Keyframe) lower((E) currKey);
		} catch (NullPointerException e) {
			prevKey = currKey;
		}
		try {
			nextKey = (Keyframe) higher((E) currKey);
		} catch (NullPointerException e) {
			nextKey = currKey;
		}
		if (prevKey == null) {
			prevKey = currKey;
		}

		if (nextKey == null) {
			switch (endBehavior) {
				case LOOP:
					nextKey = (Keyframe) first();
					break;
				default:
					nextKey = currKey;
					break;
			}
		}

		
		duration = ((Keyframe) last()).time;
	}

	public long currTime(long worldTime) {
		long currTime = 0;
		boolean doAdvance = false;
		;
		switch (endBehavior) {
			case RESET:
				if (worldTime > duration) {
					currTime = 0;
				}
				break;
			case LOOP:
				if (duration != 0) {
					currTime = worldTime % duration;
				} else {
					currTime = 0;
				}
				break;
			case CONSTANT:
				if (worldTime > duration) {
					currTime = duration;
				}
				break;
		}

		return currTime;
	}
}
